package com.example.concurrentprogramming8016.reetrantlock;

import lombok.extern.slf4j.Slf4j;

import java.sql.Time;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//默认是非公平的 传递true参数  是公平锁

/**
 * 非公平锁是多个线程加锁时直接尝试获取锁，获取不到才会到等待队列的队尾等待。
 * 但如果此时锁刚好可用，那么这个线程可以无需阻塞直接获取到锁，
 * 所以非公平锁有可能出现后申请锁的线程先获取锁的场景。
 * 非公平锁的优点是可以减少唤起线程的开销，整体的吞吐效率高。
 *
 * 缺点： 处于等待队列中的线程就算先到也可能会等很久才会获得锁
 */
@Slf4j
public class ReentrantLockDemo6 {
    public static void main(String[] args) throws InterruptedException {
        ReentrantLock reentrantLock = new ReentrantLock(true);//公平锁

        for (int i = 0; i < 500; i++) {
            new Thread(() -> {
                reentrantLock.lock();
                try {
                    TimeUnit.MILLISECONDS.sleep(10);
                    log.debug(Thread.currentThread().getName() + " running...");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                } finally {
                    reentrantLock.unlock();
                }

            }, "t-" + i).start();
        }

        TimeUnit.SECONDS.sleep(1);

        for (int i = 0; i < 500; i++) {
            new Thread(() -> {
                reentrantLock.lock();
                log.debug(Thread.currentThread().getName() + " running...");
                reentrantLock.unlock();
            }, " 强制插入 " + i).start();
        }


    }
}
